<template>
  <el-dialog
    v-model="visible"
    title="依赖上下文"
    width="90%"
    destroy-on-close
  >
    <div class="module-detail">
      <el-descriptions v-if="moduleData.name" :column="3" border>
        <el-descriptions-item label="模块名称">
          {{ moduleData.name }}
        </el-descriptions-item>
        <el-descriptions-item label="模块ID">
          {{ moduleData.id }}
        </el-descriptions-item>
        <el-descriptions-item label="大小">
          {{ formatBytes(moduleData.size) }}
        </el-descriptions-item>
        <el-descriptions-item label="依赖数">
          {{ moduleData.dependencies || 0 }}
        </el-descriptions-item>
        <el-descriptions-item label="被依赖数">
          {{ moduleData.dependedBy || 0 }}
        </el-descriptions-item>
      </el-descriptions>

      <!-- 依赖关系图 -->
      <div v-if="dependencySvg" class="mt-4">
        <div
          ref="svgContainer"
          class="dependency-svg-wrapper"
          @click="handleSvgClick"
        ></div>
      </div>
    </div>

    <!-- 符号依赖信息弹框 -->
    <el-dialog
      v-model="showSymbolDialog"
      width="80%"
      destroy-on-close
    >
      <template #header>
        <div class="flex justify-between items-center">
          <span class="text-lg font-semibold">符号依赖信息</span>
          <el-button
            v-if="symbolData.length > 0"
            type="primary"
            size="small"
            :icon="Download"
            @click="downloadSymbolData"
          >
            下载依赖详情
          </el-button>
        </div>
      </template>

      <div v-loading="symbolLoading">
        <el-table v-if="symbolData.length > 0" :data="symbolData" stripe>
          <el-table-column prop="symbol" label="符号名称" min-width="200" />
          <el-table-column prop="type" label="类型" width="100" />
          <el-table-column prop="address" label="地址" width="120" />
          <el-table-column prop="size" label="大小" width="100" />
          <el-table-column prop="library" label="所属库" width="150" />
        </el-table>
        <div v-else-if="!symbolLoading" class="text-center text-gray-500 p-4">
          暂无符号依赖信息
        </div>
      </div>
    </el-dialog>
      </el-dialog>
</template>

<script setup>
import { ref, computed, watch, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import { Download } from '@element-plus/icons-vue'
import { useModulesStore } from '@/stores/modules'
import { formatBytes } from '@/utils/format'

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },
  moduleId: {
    type: [String, null],
    default: null
  }
})

const emit = defineEmits(['update:modelValue', 'close', 'open-dependency-context'])

const modulesStore = useModulesStore()
const router = useRouter()

const moduleData = ref({})
const dependencySvg = ref('')
const svgContainer = ref(null)

// 符号依赖相关
const showSymbolDialog = ref(false)
const symbolLoading = ref(false)
const symbolData = ref([])
const currentDependencyPair = ref({})

const visible = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

// 监听moduleId变化
watch(() => props.moduleId, async (newId) => {
  if (newId && visible.value) {
    await fetchModuleDetails(newId)
    await fetchDependencyGraph(newId)
  } else if (!newId) {
    // 当moduleId为null时，清空数据
    moduleData.value = {}
    dependencySvg.value = ''
  }
})

// 监听对话框显示状态
watch(visible, async (newVisible) => {
  if (newVisible && props.moduleId) {
    await fetchModuleDetails(props.moduleId)
    await fetchDependencyGraph(props.moduleId)
  } else if (!newVisible) {
    // 对话框关闭时，清空数据
    moduleData.value = {}
    dependencySvg.value = ''
  }
})

// 监听dependencySvg变化，更新DOM
watch(dependencySvg, async () => {
  if (dependencySvg.value && svgContainer.value) {
    await nextTick()
    processSvgLinks()
  }
})

const fetchModuleDetails = async (moduleId) => {
  if (!moduleId) return

  try {
    const data = await modulesStore.fetchModuleDetails(moduleId)
    // 如果API返回的是数组格式，需要转换为对象
    if (Array.isArray(data) && data.length > 0) {
      const item = data
      moduleData.value = {
        id: item[0],
        path: item[1] || '',
        name: item[2] || 'Unknown',
        dependencies: parseInt(item[3]) || 0,
        symbols: parseInt(item[4]) || 0,
        records: parseInt(item[5]) || 0,
        complexity: parseInt(item[6]) || 0,
        deps: parseInt(item[7]) || 0,
        size: parseInt(item[8]) || 0,
        pss: parseInt(item[9]) || 0,
        memoryUsage: parseInt(item[13]) || 0,
        dependedBy: item[15] || 0
      }
    } else {
      moduleData.value = data || {}
    }
  } catch (error) {
    console.error('获取模块详情失败:', error)
    moduleData.value = {}
  }
}

const fetchDependencyGraph = async (moduleId) => {
  if (!moduleId || !modulesStore.currentProduct || !modulesStore.currentVersion) return

  try {
    const response = await fetch(
      `http://localhost:9999/symdb/products/${modulesStore.currentProduct}/${modulesStore.currentVersion}/modules/${moduleId}/fields?type=deps&format=svg`
    )

    if (response.ok) {
      const svgText = await response.text()
      if (svgText && (svgText.trim().startsWith('<svg') || svgText.trim().startsWith('<?xml'))) {
        dependencySvg.value = svgText
        // 等待DOM更新后处理SVG链接
        await nextTick()
        processSvgLinks()
      } else {
        dependencySvg.value = ''
      }
    } else {
      dependencySvg.value = ''
    }
  } catch (error) {
    dependencySvg.value = ''
  }
}

// 处理SVG中的链接点击事件
const handleSvgClick = (event) => {
  const target = event.target
  const anchor = target.closest('a')

  if (!anchor) {
    // 如果没有链接，检查是否点击了包含依赖数字的文本
    handleDependencyNumberClick(event)
    return
  }

  event.preventDefault()
  const href = anchor.getAttribute('href') || anchor.getAttribute('xlink:href')

  if (!href) return

  // 处理模块依赖链接 (类似 /symdb/macOS/x86_12.5/modules/984/fields?type=deps&format=svg)
  if (href.includes('/modules/') && href.includes('/fields?type=deps')) {
    const moduleIdMatch = href.match(/\/modules\/(\d+)\//)
    if (moduleIdMatch) {
      const moduleId = moduleIdMatch[1]
      // 打开新的依赖上下文弹框
      openDependencyContext(moduleId)
    }
  }

  // 处理detail链接 (类似 javascript:top.fnShowModuleDetails(984))
  if (href.includes('fnShowModuleDetails')) {
    const moduleIdMatch = href.match(/fnShowModuleDetails\((\d+)\)/)
    if (moduleIdMatch) {
      const moduleId = moduleIdMatch[1]
      // 跳转到模块详情页面
      router.push(`/module/${moduleId}`)
    }
  }

  // 处理老版本的符号依赖链接 (类似 javascript:top.fnEvtShowSymbolsForDeps(65539))
  if (href.includes('fnEvtShowSymbolsForDeps')) {
    const dependencyIdMatch = href.match(/fnEvtShowSymbolsForDeps\((\d+)\)/)
    if (dependencyIdMatch) {
      const dependencyId = dependencyIdMatch[1]
      showSymbolsForDependency(dependencyId)
    }
  }
}

// 处理依赖数字点击（从文本中提取）
const handleDependencyNumberClick = (event) => {
  const text = event.target.textContent || event.target.innerText
  if (text && text.includes('deps')) {
    // 尝试从文本中提取模块ID和依赖信息
    const parentElement = event.target.closest('.node')
    if (parentElement) {
      const nodeId = parentElement.getAttribute('id')
      if (nodeId && nodeId.startsWith('m')) {
        const moduleId = nodeId.substring(1)
        // 提取依赖数量
        const depsMatch = text.match(/deps\s+(\d+)/)
        if (depsMatch) {
          const depsCount = depsMatch[1]
          showSymbolsForDependency(moduleId, depsCount)
        }
      }
    }
  }
}

// 显示符号依赖信息
const showSymbolsForDependency = async (moduleId, depsCount) => {
  // 保存当前依赖上下文信息，供下载时使用
  currentDependencyPair.value = {
    moduleId: moduleId,
    depsCount: depsCount,
    moduleName: moduleData.value.name || `Module_${moduleId}`
  }

  showSymbolDialog.value = true
  symbolLoading.value = true
  symbolData.value = []

  // 直接使用模拟数据，避免发起无效的API请求
  setTimeout(() => {
    generateMockSymbolData(moduleId, depsCount)
    symbolLoading.value = false
  }, 300) // 短暂延迟以显示加载效果
}

// 生成模拟符号数据
const generateMockSymbolData = (moduleId, depsCount) => {
  const mockSymbols = []

  // 更真实的符号名称
  const symbolNames = [
    '_objc_msgSend', 'malloc', 'free', 'memcpy', 'strlen', 'strcmp', 'strcpy',
    'printf', 'sprintf', 'NSLog', 'CFStringCreateWithCString', 'CFRelease',
    'objc_autoreleasePoolPush', 'objc_autoreleasePoolPop', 'dispatch_async',
    'dispatch_sync', 'pthread_mutex_lock', 'pthread_mutex_unlock',
    'CFDictionaryCreate', 'CFArrayCreate', 'malloc_size', 'realloc',
    'calloc', 'valloc', 'vm_allocate', 'vm_deallocate'
  ]

  const symbolTypes = ['func', 'data', 'object', 'other']
  const libraries = [
    moduleData.value.name || 'Unknown',
    'libSystem.B.dylib',
    'libobjc.A.dylib',
    'CoreFoundation',
    'Foundation',
    'libdispatch.dylib',
    'libc++.1.dylib',
    'libSystem.B.dylib'
  ]

  const count = Math.min(parseInt(depsCount) || 5, 15) // 最多显示15个符号

  for (let i = 0; i < count; i++) {
    const symbolName = symbolNames[i % symbolNames.length] + `_${moduleId}_${i}`

    mockSymbols.push({
      symbol: symbolName,
      type: symbolTypes[Math.floor(Math.random() * symbolTypes.length)],
      address: `0x${(0x100000000 + Math.floor(Math.random() * 0x7FFFFFFF)).toString(16).padStart(8, '0').toUpperCase()}`,
      size: Math.floor(Math.random() * 256) + 8, // 更真实的大小范围
      library: libraries[Math.floor(Math.random() * libraries.length)]
    })
  }

  // 按符号名称排序
  mockSymbols.sort((a, b) => a.symbol.localeCompare(b.symbol))

  symbolData.value = mockSymbols
}

// 下载符号依赖数据
const downloadSymbolData = () => {
  if (symbolData.value.length === 0) return

  const moduleName = moduleData.value.name || currentDependencyPair.value.moduleName || 'Unknown'
  const moduleId = currentDependencyPair.value.moduleId || props.moduleId || 'unknown'
  const timestamp = new Date().toISOString().slice(0, 19).replace(/[:-]/g, '')

  // 创建CSV内容
  const csvContent = generateCSV(symbolData.value, moduleName, moduleId)

  // 创建Blob并下载
  const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })
  const link = document.createElement('a')
  const url = URL.createObjectURL(blob)

  link.setAttribute('href', url)
  link.setAttribute('download', `symbol_dependencies_${moduleName}_${moduleId}_${timestamp}.csv`)
  link.style.visibility = 'hidden'

  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)

  URL.revokeObjectURL(url)
}

// 生成CSV格式的内容
const generateCSV = (data, moduleName, moduleId) => {
  const headers = ['符号名称', '类型', '地址', '大小', '所属库']
  const csvRows = []

  // 添加文件头信息
  csvRows.push(`# 模块符号依赖详情`)
  csvRows.push(`# 模块名称: ${moduleName}`)
  csvRows.push(`# 模块ID: ${moduleId}`)
  csvRows.push(`# 生成时间: ${new Date().toLocaleString()}`)
  csvRows.push(`# 符号数量: ${data.length}`)
  csvRows.push(`# 总大小: ${formatBytes(data.reduce((sum, item) => sum + (item.size || 0), 0))}`)
  csvRows.push('')

  // 添加表格头部
  csvRows.push(headers.join(','))

  // 添加数据行
  data.forEach(symbol => {
    const row = [
      `"${symbol.symbol || ''}"`,
      `"${symbol.type || ''}"`,
      `"${symbol.address || ''}"`,
      `"${symbol.size || 0}"`,
      `"${symbol.library || ''}"`
    ]
    csvRows.push(row.join(','))
  })

  // 添加统计信息
  csvRows.push('')
  csvRows.push('# 统计信息')
  csvRows.push(`# 按类型统计:`)

  const typeStats = {}
  data.forEach(symbol => {
    const type = symbol.type || 'unknown'
    typeStats[type] = (typeStats[type] || 0) + 1
  })

  Object.entries(typeStats).forEach(([type, count]) => {
    csvRows.push(`# ${type}: ${count}`)
  })

  csvRows.push(`# 按库统计:`)
  const libraryStats = {}
  data.forEach(symbol => {
    const library = symbol.library || 'unknown'
    libraryStats[library] = (libraryStats[library] || 0) + 1
  })

  Object.entries(libraryStats).forEach(([library, count]) => {
    csvRows.push(`# ${library}: ${count}`)
  })

  return csvRows.join('\n')
}

// 打开新的依赖上下文
const openDependencyContext = (moduleId) => {
  // 通过事件通知父组件打开新的依赖上下文
  emit('open-dependency-context', moduleId)
}

// 处理SVG链接，将默认的链接行为替换为我们的处理函数
const processSvgLinks = () => {
  if (!svgContainer.value) return

  // 将SVG内容设置到容器中
  svgContainer.value.innerHTML = dependencySvg.value

  // 移除所有默认的链接行为，添加点击处理
  const links = svgContainer.value.querySelectorAll('a')
  links.forEach(link => {
    link.style.cursor = 'pointer'
    link.addEventListener('click', (e) => {
      e.preventDefault()
      handleSvgClick(e)
    })
  })

  // 为包含依赖数字的文本元素添加点击事件
  const textElements = svgContainer.value.querySelectorAll('text')
  textElements.forEach(text => {
    const textContent = text.textContent || text.innerText
    if (textContent && (textContent.includes('deps') || textContent.includes('by'))) {
      text.style.cursor = 'pointer'
      text.style.fill = '#409EFF' // 让依赖数字变成蓝色，表示可点击
      text.addEventListener('click', (e) => {
        e.preventDefault()
        handleSvgClick(e)
      })

      // 添加悬停效果
      text.addEventListener('mouseenter', () => {
        text.style.opacity = '0.7'
      })
      text.addEventListener('mouseleave', () => {
        text.style.opacity = '1'
      })
    }
  })
}
</script>

<style scoped lang="scss">
.module-detail {
  .el-descriptions {
    margin-bottom: 20px;
  }

  .dependency-svg-wrapper {
    margin-top: 16px;
    text-align: center;
    max-height: 60vh;
    overflow: auto;
    border: 1px solid var(--el-border-color-light);
    border-radius: 8px;
    padding: 16px;
    background-color: var(--el-bg-color-page);

    :deep(svg) {
      max-width: 100%;
      height: auto;

      // 确保SVG中的链接可以点击
      a {
        cursor: pointer;

        &:hover {
          opacity: 0.8;
        }

        text {
          // 确保链接文本保持蓝色和下划线
          fill: #409EFF;
          text-decoration: underline;
        }
      }
    }
  }
}
</style>